#include "tcp_socket.hpp"
#include<signal.h>
#include <unistd.h>

//服务端
//多进程实现通信

void creat_worker(TcpSocket new_sock)
{
  //子进程完成数据的通信
  pid_t pid=fork();  //创建子进程
  if(pid<0){
    new_sock.Close();
    perror("fork error!");
    return;
  }
  if(pid>0){
    //父进程
    new_sock.Close();   //关闭父进程中的套接字描述符
    return;
  }

  //子进程实现数据的收发
  while(1){
    //5、收发数据
    std::string buf;
    bool ret = new_sock.Recv(&buf);
    if(ret==false){                                                 
      //接受失败
      new_sock.Close();   //说明连接不成立----关闭套接字
      exit(-1);   //子进程退出
    }
    std::cout<<"client say : "<<buf<<std::endl;

    buf.clear();
    std::cout<<"server say : ";
    fflush(stdout);
    std::cin>>buf;
    ret= new_sock.Send(buf);
    if(ret==false){
      new_sock.Close();
      exit(-1);
    }
  }
  exit(-1); //子进程在发送或接收数据出错，break 跳出循环之后会退出，不能让其继续下去与父进程一起 accept 接受新建连接
}

int main(int argc,char* argv[])
{
  if(argc!=3){
    std::cout<<"nUsage:./tcp_ser 192.168.75.128 9000"<<std::endl;
    return -1;
  }
  signal(SIGCHLD,SIG_IGN);//忽略子进程退出返回值

  std::string ip=argv[1];
  uint16_t port=atoi(argv[2]);

  TcpSocket lsn_sock;  //实例化一个套接字结构对象
  //服务端
  //1、创建套接字
  assert(lsn_sock.Socket()!=false);

  //2、绑定地址
  assert(lsn_sock.Bind(ip,port));
  //3、开始监听
  assert(lsn_sock.Listen());
  while(1){
    //4、建立新连接
    TcpSocket new_sock;  //新建套接字，因为客户端连接可能不止一个，因此需要循环进行建立连接
    std::string cli_ip;
    uint16_t cli_port;
    bool ret=lsn_sock.Accept(&new_sock,&cli_ip,&cli_port);
    if(ret==false){
      //一次客户端的新建连接失败，则继续处理下一个客户端请求
      continue;
    }
    std::cout<<"new client: "<<cli_ip<<" : "<<cli_port<<std::endl;

    //创建子进程让子进程完成数据的通信
    creat_worker(new_sock);




/*
    while(1){
      //5、收发数据
      std::string buf;
      ret = new_sock.Recv(&buf);
      if(ret==false){
        //接受失败
        new_sock.Close();   //说明连接不成立----关闭套接字
        //continue;
        break;
      }
      std::cout<<cli_ip<<" : "<<cli_port<<"say : "<<buf<<std::endl;

      buf.clear();
      std::cout<<"server say : ";
      fflush(stdout);
      std::cin>>buf;
      ret = new_sock.Send(buf);
      if(ret==false){
        new_sock.Close();
        //continue;  //发送数据失败，关闭套接字
        break;
      }
    }*/
  }
  

  //6、关闭套接字
  lsn_sock.Close();  

  return 0;
}
